package net.bplaced.streetfighter.lib.service;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;

import net.bplaced.streetfighter.lib.utils.ServiceReturnPackage;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.ByteArrayBuffer;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;

/**
 * @author Sebastian Hoffmann <bo.hoffi@googlemail.com>
 */
public class CommonService<T> {

    private static final String SERVER_RESPONSE_EXCEPTION_MESSAGE =
            "Es ist ein Fehler während der Verarbeitung der Serverantwort aufgetreten. Bitte kontaktieren Sie den Serveradministrator.";
    private static final String IO_EXCEPTION_MESSAGE =
            "Es ist ein Fehler während der Verbindung mit dem Server aufgetreten. Bitte Internetverbindung prüfen.";
    private static final String JSON_SYTAX_EXCEPTION_MESSAGE = CommonService.SERVER_RESPONSE_EXCEPTION_MESSAGE;
    private static final String UNSUPPORTED_ENCODING_EXCEPTION_MESSAGE =
            CommonService.SERVER_RESPONSE_EXCEPTION_MESSAGE;

    protected ServiceReturnPackage<T> sendRequest(final HttpPost httpPost, final List<NameValuePair> parameters,
            Class<T> jsonClass) {

        final HttpClient httpClient = new DefaultHttpClient();
        final ServiceReturnPackage<T> returnPackage = new ServiceReturnPackage<T>();

        try {

            httpPost.setEntity(new UrlEncodedFormEntity(parameters));

            final HttpResponse response = httpClient.execute(httpPost);

            returnPackage.setStatus(response.getStatusLine().getStatusCode());

            if (returnPackage.getStatus() == 200) {
                final BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent());
                final ByteArrayBuffer baf = new ByteArrayBuffer(50);
                int current = 0;
                while ((current = bis.read()) != -1) {
                    baf.append((byte) current);
                }

                final Gson gson = new Gson();
                returnPackage.setContent(gson.fromJson(new String(baf.toByteArray()), jsonClass));
            }
            // TODO Wenn statusCode != 200

        } catch (final ClientProtocolException e) {
            // TODO http protocol error
            returnPackage.setContent(null);
            returnPackage.setErrorMessage(e.getMessage());
        } catch (final UnsupportedEncodingException e) {
            // Unsupported encoding
            returnPackage.setContent(null);
            returnPackage.setErrorMessage(CommonService.UNSUPPORTED_ENCODING_EXCEPTION_MESSAGE);
        } catch (final JsonSyntaxException e) {
            // Wrong syntax in server response
            returnPackage.setContent(null);
            returnPackage.setErrorMessage(CommonService.JSON_SYTAX_EXCEPTION_MESSAGE);
        } catch (final IllegalStateException e) {
            returnPackage.setContent(null);
            returnPackage.setErrorMessage(e.getMessage());
        } catch (final IOException e) {
            // Connection error e.g. no network connection
            returnPackage.setContent(null);
            returnPackage.setErrorMessage(CommonService.IO_EXCEPTION_MESSAGE);
        }

        return returnPackage;
    }
}